<template>
  <div class="ma-content-block lg:flex justify-between p-4">
    <a-spin :loading="spinLoading" :tip="spinTip" dot style="width: 100%;">
      <a-layout-content class="flex flex-col lg:h-full relative w-full">
        <div ref="searchRef">

        </div>
        <div class="table-header lg:flex justify-between mb-2">
          <a-space class="lg:flex block lg:inline-block">
            <a-button v-if="isExpandAll" type="primary" status="warning" size="small" @click="expandAll(isExpandAll)">
              <template #icon><icon-caret-down /></template>展开
            </a-button>
            <a-button v-else type="dashed" status="warning" size="small" @click="expandAll(isExpandAll)">
              <template #icon><icon-caret-up /></template>收缩
            </a-button>
            <a-button v-auth="['adminmenu/add']" type="primary" size="small" @click="add({}, 'add')">
              <template #icon><icon-plus /></template>
              <template #default>添加</template>
            </a-button>
            <a-button v-auth="['adminmenu/delete']" type="primary" status="danger" size="small" @click="batchDel()">
              <template #icon><icon-delete /></template>批量删除
            </a-button>
          </a-space>
          <a-space class="lg:mt-0 mt-2">
            <a-tooltip content="刷新表格"><a-button shape="circle" @click="refresh"><icon-refresh /></a-button></a-tooltip>
            <a-tooltip content="设置"><a-button shape="circle" @click="setTableColumns"><icon-settings /></a-button></a-tooltip>
          </a-space>
        </div>
        <div ref="tableContainerRef">
          <a-table
            ref="tableRef"
            row-key="id"
            :loading="loading"
            :pagination="false"
            :data="renderData"
            :bordered="{ wrapper: true, cell: true }"
            :row-selection="rowSelection"
            :scroll="tableScroll"
            column-resizable
            @selection-change="selectionChange"
          >
            <template #columns>
              <vue-table-column :columns="columns">
                <template #icon="{ record }">
                  <component v-if="record.icon" :is="record.icon"></component>
                </template>
                <template #titleStatus="{ record }">
                  <span>是否禁用</span>
                  <a-tooltip content="禁用后无法访问">
                    <icon-question-circle-fill />
                  </a-tooltip>
                </template>
                <template #status="{ record }">
                  <a-switch v-model="record.status" :checked-value="1" :unchecked-value="2" @change="isActivate(record)"/>
                </template>
                <template #sorting="{ record }">
                  <a-input-number v-model="record.sorting" :step="1" @blur="listOrders(record)" />
                </template>
                <template #operations="{ record }">
                  <a-dropdown>
                    <a-button type="text" size="mini">操作 <icon-down /></a-button>
                    <template #content>
                      <a-doption v-auth="['adminmenu/add']" @click="add(record, 'add')">添加子菜单</a-doption>
                      <a-doption v-auth="['adminmenu/edit']" @click="add(record, 'edit')">编辑</a-doption>
                      <a-doption v-auth="['adminmenu/delete']" class="is-danger" @click="del([record])">删除</a-doption>
                      <a-doption @click="copy(record)">复制</a-doption>
                    </template>
                  </a-dropdown>
                </template>
              </vue-table-column>
            </template>
          </a-table>
        </div>
      </a-layout-content>
    </a-spin>

    <SetColumn ref="setColumnRef" :columns="columns" @update:columns="updateColumns"/>

    <Detail ref="detailRef" :treeDatas="treeDatas" @saveCallback="fetchData"/>
    <Copy ref="copyRef" :treeDatas="treeDatas" @saveCallback="fetchData"/>
  </div>
</template>

<script setup>
  import { ref, reactive, h, compile, nextTick, onMounted, onUnmounted } from 'vue';
  import { Message, Modal } from '@arco-design/web-vue';

  import useLoading from '@/hooks/loading';
  import { workAreaHeight } from '@/utils/index';
  import tool from '@/utils/tool';
  import { apiList, apiDel, apiDisable, apiListOrders } from '@/api/admin-menu';
  import VueTableColumn from '@/components/table/table-column.vue';
  import SetColumn from '@/components/table/set-column.vue';
  import Detail from './components/detail.vue';
  import Copy from './components/copy.vue';

  const { loading, setLoading } = useLoading(false);
  const baseQuery = () => {
    return {
      page: 1,
      limit: 20,
      name: '',
      time_type: 'created_at',
      range_date: [],
    };
  };
  const baseColumns = [
    {
      title: '名称', dataIndex: 'name', width: 200,
      align: 'center', fixed: 'left',
    },
    {
      title: '应用', dataIndex: 'app',  width: 100,
      align: 'center',
    },
    {
      title: '控制器', dataIndex: 'controller',  width: 180,
      align: 'center',
    },
    {
      title: '方法', dataIndex: 'action',  width: 100,
      align: 'center',
    },
    {
      title: '路由', dataIndex: 'route',  width: 180,
      align: 'center',
    },
    {
      title: '图标', dataIndex: 'icon',  width: 80,
      align: 'center',
      slotName: 'icon',
    },
    {
      title: '启用', dataIndex: 'status',  width: 120,
      align: 'center',
      slotName: 'status', titleSlotName: 'titleStatus',
    },
    {
      title: '排序', dataIndex: 'sorting', width: 100,
      align: 'center',
      slotName: 'sorting',
    },
    {
      title: '创建时间', dataIndex: 'created_at', width: 180,
      align: 'center',
      sortable: {sortDirections: ['ascend', 'descend']},
    },
    {
      title: '操作', dataIndex: 'operations', width: 95,
      align: 'center', fixed: 'right',
      slotName: 'operations',
    },
  ];
  const columns = ref(tool.local.get('columns-admin-menu') || baseColumns);
  const renderData = ref([]);
  const query = ref(baseQuery());
  const rowSelection = reactive({
    type: 'checkbox',
    selectedRowKeys: [],
    showCheckedAll: true,
  });
  const tableScroll = ref({
    x: '100%',
    y: '100%',
  });

  const searchRef = ref();
  const showSearch = ref(true);
  const tableContainerRef = ref();
  const tableRef = ref();
  const setColumnRef = ref();
  const searchHeight = ref(0);

  const isReset = ref(true); // 是否重置
  let selectionKeys = []; // 选中项ID
  const spinLoading = ref(false);
  const spinTip = ref();
  const isExpandAll = ref(true); // 展开/收缩
  const detailRef = ref();
  const copyRef = ref();
  const treeDatas = ref();

  const settingFixedPage = () => {
    const workHeight = workAreaHeight();
    const tableHeight = workHeight - searchHeight.value;
    tableContainerRef.value.style.height = `${tableHeight}px`;
  };
  const resizeHandler = () => {
    searchHeight.value = searchRef.value.offsetHeight;
    settingFixedPage();
  };
  const toggleSearch = async () => {
    const dom = searchRef.value?.style;
    if (dom) {
      showSearch.value = !showSearch.value;
      await nextTick(() => {
        searchHeight.value = searchRef.value.offsetHeight;
        settingFixedPage();
      });
    }
  };
  const setTableColumns = () => {
    setColumnRef.value.init();
  };
  const updateColumns = (data) => {
    columns.value = data;
    tool.local.set('columns-admin-menu', columns.value);
  };

  // 列表
  const fetchData = async (
    params = { ...query.value }
  ) => {
    setLoading(true);
    await reset();
    try {
      const { data } = await apiList(params);
      renderData.value = data.data;
      treeDatas.value = data.data;
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };
  // 添加/编辑
  const add = (row = {}, type = '') => {
    detailRef.value.fetchData(row, type);
  };
  // 删除
  const del = (row) => {
    if (!row.length) {
      selectMsg();
    } else {
      let title = '删除';
      let message = `确定要删除选中的 <span style="color:red">${row.length} </span> 条数据吗？`;
      let ids = row;
      if (row.length === 1 && row[0].id) {
        title = `${title}ID：${row[0].id}`;
        message = `确定要删除 <span style="color:red">${row[0].name} </span> 这条数据吗？`;
        ids = [row[0].id];
      }
      Modal.warning({
        title,
        content: () => h('div', { innerHTML: message }),
        closable: true,
        hideCancel: false,
        onOk: (async () => {
          setLoading(true);
          try {
            await apiDel({ids});
          } catch (err) {

          } finally {
            await fetchData({...query.value});
            setLoading(false);
          }
        }),
      });
    }
  };
  // 复制
  const copy = (row) => {
    copyRef.value.fetchData(row);
  };
  // 重置
  const reset = async () => {
    if (isReset.value) {
      rowSelection.selectedRowKeys = [];
      selectionKeys = [];
    } else {
      isReset.value = true;
    }
  };
  // 搜索
  const search = async () => {
    query.value.page = 1;
    await fetchData({...query.value});
  };
  // 刷新
  const refresh = async () => {
    query.value = baseQuery();
    await fetchData({...query.value});
  };
  // 启用/禁用
  const isActivate = async (row) => {
    setLoading(true);
    await apiDisable({
      id: row.id,
      status: row.status
    });
    await fetchData({...query.value});
  };
  // 更新排序
  const listOrders = async (row) => {
    await apiListOrders({
      ids: row.id,
      sorting: row.sorting,
    }).then(res => {
      Message.success('更新排序成功');
    });
  };

  // 已选择的数据行发生改变时触发 -- table 表头
  const selectionChange = (rowKeys) => {
    rowSelection.selectedRowKeys = rowKeys;
    selectionKeys = rowKeys;
  };
  const selectMsg = (message) => {
    Message.info(message || '请选择需要操作的数据');
  };
  // 批量删除
  const batchDel = () => {
    del(selectionKeys);
  };

  // 展开/收起
  const expandAll = (isExpand) => {
    isExpandAll.value = !isExpand;
    tableRef.value.expandAll(isExpand);
  };

  onMounted(async () => {
    await fetchData();
    window.addEventListener('resize', resizeHandler, false);
    searchHeight.value = searchRef.value.offsetHeight;
    settingFixedPage();
  });
  onUnmounted(() => {
    window.removeEventListener('resize', resizeHandler, false);
  });
</script>

<script>
  export default {
    name: 'Adminmenu',
  };
</script>

<style scoped lang="less">

</style>
